package whf.framework.tools.generator;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import whf.framework.tools.generator.cfg.Config;
import whf.framework.util.StringUtils;
import whf.framework.util.Utils;

/**
 * @author wanghaifeng
 *
 */
public class ORMClassGenerator {

	private Config config;

	private String[] tables;

	private Map<String, ObjectRelationMapping> objectRelationMappings = new HashMap<String, ObjectRelationMapping>();

	public ORMClassGenerator(Config config) throws Exception {
		tables = StringUtils.split(config.getTables(),",");
		Class.forName(config.getDriver());
		Connection con = DriverManager.getConnection(config.getUrl(), config.getUsername(), config.getPassword());
		for (int i = 0; i < tables.length; i++) {
			String boClassName = Utils.getBoClassName(tables[i], config.getTablePrefix());
			Statement stmt = con.createStatement();
			try {
				ResultSet rs = stmt.executeQuery("select * from " + tables[i]
						+ " where 1=2 ");
				ResultSetMetaData rsmd = rs.getMetaData();
				String[] propNames = new String[rsmd.getColumnCount()];
				String[] propTypes = new String[rsmd.getColumnCount()];
				String[] fields = new String[rsmd.getColumnCount()];
				boolean[] updates = new boolean[rsmd.getColumnCount()];
				int[] nulls = new int[rsmd.getColumnCount()];
				for (int j = 0; j < rsmd.getColumnCount(); j++) {
					String fieldName = rsmd.getColumnName(j + 1);
					String propType = rsmd.getColumnClassName(j + 1);
					int colTypei = rsmd.getColumnType(j + 1);
					String propName = Utils.getPropertyName(fieldName);
					if ((boClassName + "_id").toLowerCase().equals(
							fieldName.toLowerCase())) {
						propName = "id";
					}
					propType = Utils.getMapType(propType, colTypei);
					propNames[j] = propName;
					propTypes[j] = propType;
					fields[j] = fieldName;
					//
					updates[j] = rsmd.isWritable(j + 1);
					nulls[j] = rsmd.isNullable(j + 1);
				}
				ObjectRelationMapping mapping = new ObjectRelationMapping(
						boClassName, tables[i], fields, propNames, propTypes);
				;
				this.objectRelationMappings.put(boClassName, mapping);
				rs.close();
			} catch (SQLException sqle) {
				sqle.printStackTrace();
			}
			stmt.close();
		}
		con.close();
	}

	public void generate() throws GeneratorException, IOException {
		Iterator boClassNames = this.objectRelationMappings.keySet().iterator();
		while (boClassNames.hasNext()) {
			String boClassName = (String) boClassNames.next();
			ObjectRelationMapping orm = (ObjectRelationMapping) this.objectRelationMappings
					.get(boClassName);
			//TODO
			ClassGenerator gen = new ClassGenerator(this.config, orm);
			gen.generate();
		}
	}

	public static void main(String[] args) throws Exception {
		ORMClassGenerator dbcc = new ORMClassGenerator(null);
		dbcc.generate();
	}

}
